<?php
namespace WxpayAPI;

use app\api\service\MemberMoney;
use think\Db;
use Des3\DES3;
use app\api\service\Message;
use app\api\service\Common;

//require_once "WxPayApi.php";
/**
 *
 * 回调基础类
 * @author widyhu
 *
 */
class WxPayNotify extends WxPayNotifyReply
{

    /**
     *
     * 回调入口
     * @param bool $needSign 是否需要签名输出
     */
    final public function Handle($needSign = true)
    {
        $msg = "OK";
        //当返回false的时候，表示notify中调用NotifyCallBack回调失败获取签名校验失败，此时直接回复失败
        $result = WxPayApi::notify(array($this, 'NotifyCallBack'), $msg);
//        file_put_contents('test.txt', date("Y-m-d H:i:s",time()) . 'result' . json_encode($result), FILE_APPEND);
        if ($result == false) {
            $this->SetReturn_code("FAIL");
            $this->SetReturn_msg($msg);
            $this->ReplyNotify(false);
            return;
        } else {
            //该分支在成功回调到NotifyCallBack方法，处理完成之后流程
            $this->SetReturn_code("SUCCESS");
            $this->SetReturn_msg("OK");
        }
        $this->ReplyNotify($needSign);
    }

    /**
     *
     * 回调方法入口，子类可重写该方法
     * 注意：
     * 1、微信回调超时时间为2s，建议用户使用异步处理流程，确认成功之后立刻回复微信服务器
     * 2、微信服务器在调用失败或者接到回包为非确认包的时候，会发起重试，需确保你的回调是可以重入
     * @param array $data 回调解释出的参数
     * @param string $msg 如果回调处理失败，可以将错误信息输出到该方法
     * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */
    //重写回调处理函数
    public function NotifyProcess($data, &$msg)
    {
        if (!array_key_exists("transaction_id", $data)) {
            $msg = "输入参数不正确";
            return false;
        }
        //查询订单，判断订单真实性
        if (!$this->Queryorder($data["transaction_id"])) {
            $msg = "订单查询失败";
            return false;
        } else {
            //return true;
            Db::startTrans();
            try {
                $pay_sn = $data["transaction_id"]; //支付单号
                $order_sn = $data['out_trade_no']; //订单号
                $order_price = $data['total_fee'] / 100; //订单支付金额
                file_put_contents('wechat_notify.txt', date('Y-m-d H:i:s') . '====== ' . json_encode($data) . " \n ", FILE_APPEND);
                $attach = json_decode($data['attach'], true); // 商家数据包
                Db::listen(function ($sql, $time, $explain) {
                    // 记录SQL
                    file_put_contents('wechat_notify.txt', date('Y-m-d H:i:s') . '====== ' . $sql . " \n ", FILE_APPEND);
                });

                // 平台支付验证
                $des = new DES3();
                if ($des->decrypt($attach['pay_check_sing']) != 'Mobom') {
                    return false; // 验证失败
                }
                if ($attach['type'] == 'order') {
                    $m = $attach['m'];
                    if ($m == 1 || $m == 2) {
                        if ($m == 1) $model = 'order_buy';  // 支付订单
                        if ($m == 2) $model = 'order_server';  // 服务订单
                    } else {
                        return false; // 订单模型错误
                    }
                    if ($model == 'order_server') {
                        $order = Db::table('mob_' . $model)->alias('o')
                            ->field('o.member_id, o.repair_id, o.status, o.id, o.order_price, m.parent_id, r.repair_name')
                            ->join('mob_member m', 'm.id = o.member_id')
                            ->join('mob_repair r', 'r.id = o.repair_id')
                            ->where('o.order_sn', $order_sn)
                            ->find();
                        $msg = $order['repair_name'] . '- 服务单支付';
                    }

                    if ($model == 'order_buy') {

                    }
                    if (($model == 'order_server' && $order['status'] != 2) || ($model == 'order_buy' && $order['status'] != 1)) {
                        return true; // 订单状态已付款
                    }

                    //增加用户支付账单
                    MemberMoney::add_member_money($order['member_id'], $order_price, 1, 0, $msg, 9, $order_sn, $model, '微信支付');

                    //订单业务
                    if ($model == 'order_server') {
                        // 获取订单维修店信息
                        $merchant = Db::table('mob_order_server')->alias('o')
                            ->field('o.id order_id, o.order_sn, o.order_price, r.id, r.member_id, m.phone, m.openid, role.nickname')
                            ->join('mob_repair r', 'r.id = o.repair_id')
                            ->join('mob_member m', 'r.member_id = m.id')
                            ->join('mob_member_role_info role', 'role.member_id = m.id')
                            ->where('o.order_sn', $order_sn)
                            ->find();

                        // 给维修店增加待结算金额  以订单总金额为准
                        Db::table('mob_repair')->where('id', $merchant['id'])->setInc('money_frozen', $order['order_price']);

                        //增加维修店收款账单
                        MemberMoney::add_member_money($merchant['member_id'], $order['order_price'], 1, 1, $merchant['nickname'] . ' - 服务单收款', 1, $order_sn, $model, '微信支付');
                        $order_data['status'] = 3; // 已付款状态
                    } else {
                        // 店铺商城功能尚未完成
                        $merchant = [];
                        $order_data['status'] = 2; // 已付款状态
                    }
                    $order_data['order_price_payment'] = $order_price;  // 实付金额， 已微信返回为准
                    $order_data['pay_time'] = time();  // 支付时间
                    $order_data['pay_type'] = 'weixin'; // 支付类型
                    $order_data['pay_sn'] = $pay_sn; // 支付单号
                    if (isset($attach['c']) && $attach['c'] > 0) { // 优惠券使用信息
                        $order_data['coupon_id'] = $attach['c']; // 优惠券ID
                        $order_data['coupon_money'] = $attach['cp']; // 优惠金额
                        Db::table('mob_member_coupon')->where('id', $attach['c'])->update(['status' => 1]); // 修改优惠券状态
                    }
                    Db::table('mob_' . $model)->where('order_sn', $order_sn)->update($order_data);

                    /*********
                     *    订单支付成功  提醒商家
                     *
                     ***/
                    // 发送短信
                    $params[] = $merchant['order_sn'];
                    $param = ['phone' => $merchant['phone'], 'type' => 33, 'model' => 3063083, 'params' => json_encode($params)];
                    Common::send_note($param);
                    // 发送微信模板消息
                    $url = 'http://' . $_SERVER['HTTP_HOST'] . '/wechat/r_member/order_info.html?id=' . $merchant['order_id'];
                    if ($merchant['openid']) {
                        $data = [
                            'touser' => $merchant['openid'],
                            'template_id' => 'bnzQgDYgRRSaNUhN0PxIkCDzZiAaKMyX_ijEt3bjOG4',
                            'url' => $url,
                            'topcolor' => '#FF0000',
                            'data' => [
                                'first' => [
                                    'value' => '订单付款',
                                    "color" => "#173177"
                                ],
                                'keyword1' => [
                                    'value' => $merchant['order_sn'],
                                    "color" => "#173177"
                                ],
                                'keyword2' => [
                                    'value' => $merchant['order_price'],
                                    "color" => "#173177"
                                ],
                                'keyword3' => [
                                    'value' => date('Y-m-d H:i:s'),
                                    "color" => "#173177"
                                ],
                                'keyword4' => [
                                    'value' => '订单已付款，请尽快完成订单内容',
                                    "color" => "#173177"
                                ]
                            ]
                        ];
                        send_msg($data);
                    }

                    /*****
                     * 推送站内信息 *  ****/
                    $param = [
                        'member_id' => $merchant['member_id'],
                        'member_role' => 'repair',
                        'msg_id' => 38,
                        'data' => [
                            $merchant['order_sn'],
                            $merchant['order_price'],
                            date('Y-m-d H:i:s'),
                            'url' => $url,
                            'id' => $merchant['order_id'],
                            'action' => 1
                        ]
                    ];
                    Message::creation_order_msg($param);
                    /***** * 推送站内信息 --end *  ****/

                    //}
                } else if ($attach['type'] == 'deal') {
                    //$model = $attach['model'];
                    //if ($model == 'order_server_deal' ) { // 订单支付业务处理

                    $order = Db::table('mob_order_server_deal')->alias('o')
                        ->field('o.obj_member_id, o.obj_id, o.obj_type, o.dealer_id, o.status, o.id, m.parent_id ')
                        ->join('mob_member m', 'm.id = o.obj_member_id')
                        ->where('o.order_sn', $order_sn)
                        ->find();

                    if ($order['status'] != 2) {
                        return true; // 订单状态已付款
                    }
                    // 获取收款方 - 经销商  名称
                    $dealer_name = Db::table('mob_dealer')->where('id', $order['dealer_id'])->value('dealer_name');

                    //增加用户采购单支付账单
                    MemberMoney::add_member_money($order['obj_member_id'], $order_price, 1, $order['obj_type'], $dealer_name . ' - 销售单支付', 9, $order_sn, 'order_server_deal', '微信支付');

                    // 获取付款用户角色信息
                    $merchant = Db::table('mob_order_server_deal')->alias('o')
                        ->field('o.id order_id, o.order_sn, o.order_price, r.id, r.member_id, m.phone, m.openid')
                        ->join('mob_dealer d', 'd.id = o.dealer_id')
                        ->join('mob_member m', 'd.member_id = m.id')
                        ->where('o.order_sn', $order_sn)
                        ->find();

                    $tables = ['', 'repair', 'dealer'];
                    $table = $tables[$order['obj_type']];
                    $obj_name = Db::table('mob_' . $table)->where('id', $order['obj_id'])->value($table . '_name');

                    Db::table('mob_dealer')->where('id', $merchant['id'])->setInc('money_frozen', $order_price); // 给经销商增加待结算金额

                    //增加经销商采购单收款账单
                    MemberMoney::add_member_money($merchant['member_id'], $order_price, 1, 2, $obj_name . ' - 销售单收款', 1, $order_sn, 'order_server_deal', '微信支付');

                    $order_data['status'] = 3; // 已付款状态

                    $order_data['order_price_payment'] = $order_price;  // 实付金额， 已微信返回为准
                    $order_data['pay_time'] = time();  // 支付时间
                    $order_data['pay_type'] = 'weixin'; // 支付类型
                    $order_data['pay_sn'] = $pay_sn; // 支付单号
                    if (isset($attach['c']) && $attach['c'] > 0) { // 优惠券使用信息
                        $order_data['coupon_id'] = $attach['c']; // 优惠券ID
                        $order_data['coupon_money'] = $attach['cp']; // 优惠金额
                        Db::table('mob_member_coupon')->where('id', $attach['c'])->update(['status' => 1]); // 修改优惠券状态
                    }
                    Db::table('mob_order_server_deal')->where('order_sn', $order_sn)->update($order_data);

                    /*********
                     *    订单支付成功  提醒商家
                     *
                     ***/
                    // 发送短信
                    $params[] = $merchant['order_sn'];
                    $param = ['phone' => $merchant['phone'], 'type' => 33, 'model' => 3063083, 'params' => json_encode($params)];
                    Common::send_note($param);
                    // 发送微信模板消息
                    $url = 'http://' . $_SERVER['HTTP_HOST'] . '/wechat/r_orders/server_deal_goods.html?order_id=' . $merchant['order_id'];
                    if ($merchant['openid']) {
                        $data = [
                            'touser' => $merchant['openid'],
                            'template_id' => 'bnzQgDYgRRSaNUhN0PxIkCDzZiAaKMyX_ijEt3bjOG4',
                            'url' => $url,
                            'topcolor' => '#FF0000',
                            'data' => [
                                'first' => [
                                    'value' => '订单付款',
                                    "color" => "#173177"
                                ],
                                'keyword1' => [
                                    'value' => $merchant['order_sn'],
                                    "color" => "#173177"
                                ],
                                'keyword2' => [
                                    'value' => $merchant['order_price'],
                                    "color" => "#173177"
                                ],
                                'keyword3' => [
                                    'value' => date('Y-m-d H:i:s'),
                                    "color" => "#173177"
                                ],
                                'keyword4' => [
                                    'value' => '订单已付款，请尽快完成订单内容',
                                    "color" => "#173177"
                                ]
                            ]
                        ];
                        send_msg($data);
                    }

                    /*****
                     * 推送站内信息 *  ****/
                    $param = [
                        'member_id' => $merchant['member_id'],
                        'member_role' => 'repair',
                        'msg_id' => 38,
                        'data' => [
                            $merchant['order_sn'],
                            $merchant['order_price'],
                            date('Y-m-d H:i:s'),
                            'url' => $url,
                            'id' => $merchant['order_id'],
                            'action' => 2
                        ]
                    ];
                    Message::creation_order_msg($param);
                    /***** * 推送站内信息 --end *  ****/

                    //}

                } else if ($attach['type'] == 'recharge') {
                    $order = Db::table('mob_order_recharge')->where('order_sn', $order_sn)->find();
                    if ($order['status'] == 1) {
                        return true; // 订单状态已付款
                    }
                    //增加用户充值账单
                    MemberMoney::add_member_money($order['member_id'], $order_price, 0, $attach['member_type'], '充值', 8, $order_sn, 'order_recharge', '微信支付');

                    $order_data['pay_time'] = time();  // 支付时间
                    $order_data['pay_type'] = 'weixin'; // 支付类型
                    $order_data['pay_sn'] = $pay_sn; // 支付单号
                    $order_data['status'] = 1; // 已付款状态
                    Db::table('mob_order_recharge')->where('order_sn', $order_sn)->update($order_data);

                    $models = [['mob_member', 'id'], ['mob_repair', 'member_id'], ['mob_dealer', 'member_id'], ['mob_partner', 'member_id']];
                    $model = $models[$attach['member_type']];
                    Db::table($model[0])->where($model[1], $order['member_id'])->setInc('money', $order_price); // 充值成功
                } else if ($attach['type'] == 'scan_pay') {
                    $order = Db::table('mob_order_scan_code_pay')->where('order_sn', $order_sn)->find();
                    if ($order['status'] == 1) {
                        return true; // 订单状态已付款
                    }

                    // 获取收款方角色名称
                    $tables = ['member', 'repair', 'dealer']; // 扫码支付收款角色   用户  维修店  经销商
                    $table = $tables[$order['obj_type']];
                    if ($order['obj_type'] == 0) {
                        $where = ['member_id' => $order['member_id'], 'type' => 0];
                        $obj_name = Db::table('mob_member_role_info')->where($where)->value('nickname');
                    } else {
                        $where = ['member_id' => $order['member_id']];
                        $obj_name = Db::table('mob_' . $table)->where($where)->value($table . '_name');
                    }

                    //增加用户扫码支付账单
                    MemberMoney::add_member_money($order['member_id'], $order_price, 0, $order['member_type'], $obj_name . ' - 扫码支付', 9, $order_sn, 'order_scan_code_pay', '微信支付');

                    $order_data['pay_time'] = time();  // 支付时间
                    $order_data['pay_type'] = 'weixin'; // 支付类型
                    $order_data['pay_sn'] = $pay_sn; // 支付单号
                    $order_data['status'] = 1; // 已付款状态
                    if (isset($attach['c']) && $attach['c'] > 0) { // 优惠券使用信息
                        $order_data['coupon_id'] = $attach['c']; // 优惠券ID
                        $order_data['coupon_money'] = $attach['cp']; // 优惠金额
                        Db::table('mob_member_coupon')->where('id', $attach['c'])->update(['status' => 1]); // 修改优惠券状态
                    }
                    Db::table('mob_order_scan_code_pay')->where('order_sn', $order_sn)->update($order_data);

                    $models = ['mob_member', 'mob_repair', 'mob_dealer', 'mob_partner'];
                    $model = $models[$order['obj_type']];
                    Db::table($model)->where('id', $order['obj_id'])->setInc('money', $order_price); // 首款成功

                    // 获取付款角色名称
                    $tables = ['member', 'repair', 'dealer', 'partner']; // 扫码支付付款角色   用户  维修店  经销商  合伙人
                    $table = $tables[$order['member_type']];
                    if ($order['member_type'] == 0) {
                        $where = ['member_id' => $order['member_id'], 'type' => 0];
                        $obj_name = Db::table('mob_member_role_info')->where($where)->value('nickname');
                    } else {
                        $where = ['member_id' => $order['member_id']];
                        $obj_name = Db::table('mob_' . $table)->where($where)->value($table . '_name');
                    }
                    //增加用户扫码收款账单
                    MemberMoney::add_member_money($order['obj_member_id'], $order_price, 0, $order['obj_type'], $obj_name . ' - 扫码收款', 13, $order_sn, 'order_scan_code_pay', '微信支付');

                    $settlement_amount = $order['order_price']; // 结算金额以订单金额为准
                    $poundage = $settlement_amount * config('system.scan_order_proportion');;  // 计算 手续费
                    
                    // 计算分销金额
                    MemberMoney::member_distribution_earnings($order['member_id'], $poundage, $order['order_sn'], 'order_scan_code_pay');
                    // 计算合伙人服务费
                    MemberMoney::partner_service_charge_earnings('repair', $order['repair_id'], $poundage, $order['order_sn'], 'order_scan_code_pay');
                }

                // 提交事务
                Db::commit();
                return true;
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                return false;
            }
        }
    }

    /**
     *
     * notify回调方法，该方法中需要赋值需要输出的参数,不可重写
     * @param array $data
     * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */
    final public function NotifyCallBack($data)
    {
        $msg = "OK";
        $result = $this->NotifyProcess($data, $msg);

        if ($result == true) {
            $this->SetReturn_code("SUCCESS");
            $this->SetReturn_msg("OK");
        } else {
            $this->SetReturn_code("FAIL");
            $this->SetReturn_msg($msg);
        }
        return $result;
    }

    /**
     *
     * 回复通知
     * @param bool $needSign 是否需要签名输出
     */
    final private function ReplyNotify($needSign = true)
    {
        //如果需要签名
        if ($needSign == true && $this->GetReturn_code() == "SUCCESS") {
            $this->SetSign();
        }
        $xml = $this->ToXml();
//        file_put_contents("test.txt", $xml, FILE_APPEND);
        WxPayApi::replyNotify($xml);
    }

    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);
        $result = WxPayApi::orderQuery($input);
        //\Think\Log::record("query:" . json_encode($result));
        if (array_key_exists("return_code", $result) && array_key_exists("result_code", $result) && $result["return_code"] == "SUCCESS" && $result["result_code"] == "SUCCESS") {
            return true;
        }
        return false;
    }

}
